home *** CD-ROM | disk | FTP | other *** search
- // Copyright 1992 by Jon Dart. All Rights Reserved.
-
- #ifndef _HASH_H
- #define _HASH_H
-
- #include "slist.h"
- #include <assert.h>
-
- template <class Contents>
- class Hash
- {
- // "generic" hash table class, stores entries of type "Contents".
-
- public:
-
- Hash(const unsigned size, const unsigned long max_entries);
-
- ~Hash();
-
- Contents * search( const Contents &c );
- // searches hash table for a position matching c
-
- void insert(const Contents &p);
- // insert a new position in the hash table.
-
- void clear(Boolean final = False);
- // clear the hash table
-
- unsigned long num_entries() const;
-
- private:
-
- unsigned my_size;
- unsigned long my_max_entries;
- S_List<Contents> **ht;
- unsigned long hash_entries;
- };
-
- #include <stddef.h>
-
- template <class Contents>
- Hash<Contents>::Hash(const unsigned size,
- const unsigned long max_entries)
- {
- my_size = size;
- my_max_entries = max_entries;
- hash_entries = 0L;
- ht = new S_List<Contents> * [my_size];
- assert(ht);
- for (int i=0;i<my_size;i++)
- ht[i] = NULL;
- }
-
- template <class Contents>
- Hash<Contents>::~Hash()
- {
- for (int i=0;i<my_size;i++)
- {
- delete ht[i];
- }
- delete [] ht;
- }
-
- template <class Contents>
- Contents * Hash<Contents>::search( const Contents &to_match )
- {
- unsigned probe = (unsigned)(hash_code(to_match) % my_size);
- S_List<Contents> *entry = ht[probe];
- if (!entry)
- return NULL;
- entry->Rewind();
- for (Contents *c = entry->Current(); c; c = entry->Next())
- {
- if (*c == to_match)
- return c;
- }
- return NULL;
- }
-
- template <class Contents>
- void Hash<Contents>::insert(const Contents &p)
- {
- if (hash_entries >= my_max_entries)
- return;
- hash_entries++;
- unsigned long h = hash_code(p);
- unsigned probe = (unsigned)(h % my_size);
- S_List<Contents> *entry = ht[probe];
- if (!entry)
- {
- ht[probe] = new S_List<Contents>;
- assert(ht[probe]);
- ht[probe]->Insert(p);
- }
- else
- {
- entry->Rewind();
- Contents *c = entry->Current();
- while (c)
- {
- if (*c == p)
- return; // already in there
- c = entry->Next();
- }
- entry->Insert(p);
- }
- }
-
- template <class Contents>
- void Hash<Contents>::clear(Boolean final)
- {
- for (int i=0;i<my_size;i++)
- {
- ht[i] = NULL;
- }
- // free all lists:
- S_List<Contents>::freeAll(final);
- // free all nodes:
- S_Node<Contents>::freeAll(final);
- hash_entries = 0;
- }
-
- template <class Contents>
- unsigned long Hash<Contents>::num_entries() const
- {
- return hash_entries;
- }
-
- #endif
-
-